﻿
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Joins;
using System.Reactive.Linq;
using System.Reactive.PlatformServices;
using System.Reactive.Subjects;
using System.Reactive.Threading;
using System.Reactive.Threading.Tasks;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;

using agree;
using agree.itsdb;
using agree.schema;
using agree.composition;

using alib.Concurrency;
using alib.Debugging;
using alib.Enumerable;
using alib.Int;
using alib.Observable;
using alib.String;
using alib.String.Builder;

namespace agree
{
	public class txt_col
	{
		public String section;
		public String header;
		public int width;
		public ConsoleColor color;
		public Func<f_console, ParseControl, String> getter;
		public int cx;

		public void write(f_console con, int cy, ParseControl ctrl)
		{
			var s = getter(con, ctrl);
			if (String.IsNullOrWhiteSpace(s))
				return;
			if (s.Length > width)
				s = s.Substring(0, width);
			else if (s.Length < width)
				s = s.PadLeft(width);

			Console.ForegroundColor = color;
			Console.SetCursorPosition((con.cd.bw - con.cx_hdr) + cx, cy);
			Console.Write(s);
			Console.ResetColor();
		}
	};

	public class ColDefs //: Dictionary<String, txt_col>
	{
		public ColDefs()
		{
			Console.OutputEncoding = Encoding.UTF8;
			Console.ForegroundColor = (ConsoleColor)7;

			bw = Console.BufferWidth - 1;

			hdra = cols
				.GroupBy(c => c.section)
				.Select(g =>
				{
					var tot = g.Sum(tc => tc.width) - 2;
					var sg = g.Key.Length >= tot ? g.Key.Substring(0, tot) : g.Key.PadCenter(tot, '-');
					return "+" + sg + "+";
				})
				.StringJoin(" ");


			int _cx = 0;
			hdrb = cols
				.GroupBy(c => c.section)
				.Select(g =>
				{
					var ss = g.Select(tc =>
					{
						//base.Add(tc.section + "." + tc.header, tc);

						var w = tc.width;
						tc.cx = _cx;
						_cx += w;
						return tc.header.Length > w ? tc.header.Substring(0, w) : tc.header.PadLeft(w);
					})
					.StringJoin("");
					_cx++;
					return ss;
				})
				.StringJoin(" ");

			Console.Out.WriteLine(hdra.PadLeft(bw));
			Console.ForegroundColor = ConsoleColor.Cyan;
			Console.Out.WriteLine(hdrb.PadLeft(bw));
			Console.ResetColor();
		}

		//int jj;
		public void Update(f_console con, int cy, ParseControl ctrl, IString _item)
		{
			lock (Console.Out)
				for (int i = 0; i < cols.Length; i++)
					cols[i].write(con, cy, ctrl);

			//var d = ctrl.Forest.UnpackAll;//.ToArrayWait()[0];

			var item = (Item)_item;

			//Debug.Print("{0} {1} {2}", jj++, item.ExternalId, item.ExpectedDerivationCount);
			//Debug.WriteLine(item.Text.Replace(" ", ""));
			//Debug.WriteLine(item.Translations[0].Text);
#if PMRS_CONTROL
			var pmrs = new Pmrs.PortableMrs(ctrl, d.Tfs);
			Debug.WriteLine(pmrs.TextDisplay());
#endif
		}

		public int bw;

		public String hdra, hdrb;

		public static txt_col[] cols = 
		{
			/////////////////////////////////////////////////////////
			/// TOTALS
			/////////////////////////////////////////////////////////
			new txt_col 
			{
				section="totals",
				header="read",
				color=ConsoleColor.Magenta,
				width = 6,
				getter = (con,ctrl)=>
				{
					return ctrl.Forest.Unpack.ValidateAll.Count.ToString();
				},
			},
			new txt_col 
			{
				section="totals",
				header="wall",
				color=ConsoleColor.Green,
				width = 7,
				getter = (con,ctrl)=>
				{
					return (ctrl.tick_total / 10000000.0).ToString("#.###");
				},
			},
			//new txt_col 
			//{
			//	section="totals",
			//	header="unif",
			//	color=ConsoleColor.DarkRed,
			//	width = 8,
			//	getter = (con,ctrl)=>
			//	{
			//		return "123456";
			//	},
			//},
#if ERG
			/////////////////////////////////////////////////////////
			/// REPP
			/////////////////////////////////////////////////////////

			new txt_col 
			{
				section="repp",
				header="out",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.ReppExecutor.c_item_count.ToString();
				},
			},

			/////////////////////////////////////////////////////////
			/// TOKEN MAPPING
			/////////////////////////////////////////////////////////

			new txt_col 
			{
				section="tm",
				header="in",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.MappingTokenBuilder.c_in.ToString();
				},
			},
			new txt_col 
			{
				section="tm",
				header="out",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.TokenMappingLattice.EdgeCount.ToString();
				},
			},

			/////////////////////////////////////////////////////////
			/// MORPH
			/////////////////////////////////////////////////////////

			//new txt_col 
			//{
			//	section="morph",
			//	header="%t",
			//	color=ConsoleColor.DarkRed,
			//	width = 2,
			//	getter = (con,ctrl)=>
			//	{
			//		return "0";
			//	},
			//},
			new txt_col 
			{
				section="morph",
				header="unif",
				color=ConsoleColor.DarkRed,
				width = 6,
				getter = (con,ctrl)=>
				{
					return ctrl.MorphologyExecutor.c_unif.ToString();
				},
			},
			//new txt_col 
			//{
			//	section="morph",
			//	header="%",
			//	color=ConsoleColor.DarkRed,
			//	width = 3,
			//	getter = (con,ctrl)=>
			//	{
			//		return "";
			//	},
			//},
			new txt_col 
			{
				section="morph",
				header="in",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.MorphologyExecutor.c_tok_in.ToString();
				},
			},
			new txt_col 
			{
				section="morph",
				header="ntv",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.MorphologyExecutor.c_native_out.ToString();
				},
			},
			new txt_col 
			{
				section="morph",
				header="gen",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.MorphologyExecutor.c_generic_out.ToString();
				},
			},
			new txt_col 
			{
				section="morph",
				header="out",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.MorphologyExecutor.c_item_count.ToString();
				},
			},

			/////////////////////////////////////////////////////////
			/// CHART DEPENDENCIES
			/////////////////////////////////////////////////////////

			new txt_col 
			{
				section="dpnd",
				header="in",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.ChartDependenciesLoader.c_in.ToString();
				},
			},
			new txt_col 
			{
				section="dpnd",
				header="out",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.ChartDependenciesLoader.c_item_count.ToString();
				},
			},

			/////////////////////////////////////////////////////////
			/// LEXICAL FILTERING
			/////////////////////////////////////////////////////////

			new txt_col 
			{
				section="lfr",
				header="in",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.LexicalFilterExecutor.c_in.ToString();
				},
			},
			new txt_col 
			{
				section="lfr",
				header="ops",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.LexicalFilteringRewriter.c_rules_applied.ToString();
				},
			},
			new txt_col 
			{
				section="lfr",
				header="out",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.LexicalFilterExecutor.c_out.ToString();
				},
			},
#endif
			/////////////////////////////////////////////////////////
			/// PARSE
			/////////////////////////////////////////////////////////

			//new txt_col 
			//{
			//	section="parse",
			//	header="%t",
			//	color=ConsoleColor.DarkRed,
			//	width = 2,
			//	getter = (con,ctrl)=>
			//	{
			//		return "";
			//	},
			//},
			//new txt_col 
			//{
			//	section="parse",
			//	header="QC",
			//	color=ConsoleColor.DarkRed,
			//	width = 3,
			//	getter = (con,ctrl)=>
			//	{
			//		return "";
			//	},
			//},
			new txt_col 
			{
				section="parse",
				header="unif",
				color=ConsoleColor.DarkRed,
				width = 7,
				getter = (con,ctrl)=>
				{
					return ctrl.c_unif.ToString();
				},
			},
			//new txt_col 
			//{
			//	section="parse",
			//	header="%",
			//	color=ConsoleColor.DarkRed,
			//	width = 3,
			//	getter = (con,ctrl)=>
			//	{
			//		return "";
			//	},
			//},
			new txt_col 
			{
				section="parse",
				header="in",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.c_tok_in.ToString();
				},
			},
			//new txt_col 
			//{
			//	section="parse",
			//	header="fseq",
			//	color=ConsoleColor.DarkRed,
			//	width = 5,
			//	getter = (con,ctrl)=>
			//	{
			//		return ctrl.eq_tfs.Count.ToString();
			//	},
			//},
			new txt_col 
			{
				section="parse",
				header="act",
				color=ConsoleColor.DarkRed,
				width = 7,
				getter = (con,ctrl)=>
				{
					return ctrl.c_act.ToString();
				},
			},
			new txt_col 
			{
				section="parse",
				header="pass",
				color=ConsoleColor.DarkRed,
				width = 7,
				getter = (con,ctrl)=>
				{
					return ctrl.c_pass.ToString();
				},
			},
			new txt_col 
			{
				section="parse",
				header="span",
				color=ConsoleColor.DarkRed,
				width = 7,
				getter = (con,ctrl)=>
				{
					return ctrl.c_span.ToString();
				},
			},
			new txt_col 
			{
				section="parse",
				header="root",
				color=ConsoleColor.DarkRed,
				width = 6,
				getter = (con,ctrl)=>
				{
					return ctrl.c_root.ToString();
				},
			},
			new txt_col 
			{
				section="parse",
				header="jmax",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.c_tasks_max.ToString();
				},
			},

			/////////////////////////////////////////////////////////
			/// PACK
			/////////////////////////////////////////////////////////


			new txt_col 
			{
				section="pack",
				header="eq",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					return ctrl.c_pack_eq.ToString();
				},
			},
			new txt_col 
			{
				section="pack",
				header="fwd",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.c_pack_fwd.ToString();
				},
			},
			new txt_col 
			{
				section="pack",
				header="rev",
				color=ConsoleColor.DarkRed,
				width = 5,
				getter = (con,ctrl)=>
				{
					return ctrl.c_pack_rev.ToString();
				},
			},

			/////////////////////////////////////////////////////////
			/// UNPACK
			/////////////////////////////////////////////////////////


			new txt_col 
			{
				section="unpack",
				header="%t",
				color=ConsoleColor.DarkRed,
				width = 2,
				getter = (con,ctrl)=>
				{
					return "";
				},
			},
			new txt_col 
			{
				section="unpack",
				header="unif",
				color=ConsoleColor.DarkRed,
				width = 7,
				getter = (con,ctrl)=>
				{
					return "";
				},
			},

			/////////////////////////////////////////////////////////
			/// SYS
			/////////////////////////////////////////////////////////

			new txt_col 
			{
				section="sys",
				header="mem",
				color=ConsoleColor.DarkRed,
				width = 4,
				getter = (con,ctrl)=>
				{
					var mem = (Double)Process.GetCurrentProcess().PrivateMemorySize64 / (1024 * 1024 * 1024);
					return mem.ToString();
				},
			},
			new txt_col 
			{
				section="sys",
				header="GC",
				color=ConsoleColor.DarkRed,
				width = 3,
				getter = (con,ctrl)=>
				{
					return String.Format("{0}", GC.CollectionCount(2) - con.gen_base);
				},
			},
		};

	};

}